package com.study.cloud.apilog;

import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.Lists;
import com.study.cloud.apilog.entity.SLSProperties;
import com.study.cloud.apilog.request.BodyWrapper;
import com.study.cloud.apilog.request.RequestBodyService;
import com.study.cloud.apilog.response.ResponseBodyService;
import com.study.cloud.utils.TraceIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.*;


@Slf4j
@Component
public class GatewayLogFilter implements GlobalFilter, Ordered {
    @Autowired
    FilterExcludeUrl excludeUrl;
    @Autowired
    List<RequestBodyService> requestBodyServiceList;
    @Autowired
    List<ResponseBodyService> responseBodyServiceList;

    @Autowired
    SLSProperties slsProperties;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        System.out.println(slsProperties.toString());
        Mono<Void> process = process(exchange, chain);
        if(process != null){
            return process;
        }



        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
        // 先得到请求体
        BodyWrapper request = requestBodyServiceList.stream().filter(info -> info.isSupport(mediaType))
                .map(info -> info.handler(exchange)).findFirst().get();

        // 得到响应体
        return responseBodyServiceList.stream().filter(info->info.isSupport(mediaType))
                .map(info-> info.handler(exchange,chain,request.getGatewayApiLog(),request.getBodyInserter()))
                .findFirst().get();

    }

    @Override
    public int getOrder() {
        // 必须小于等于-2，否则无法获取相应结果
        return -2;
    }


    /**
     * 设置traceId和过滤部分url
     * @param exchange
     * @param chain
     * @return
     */
    public Mono<Void> process(ServerWebExchange exchange,GatewayFilterChain chain){
        // traceId 设置,过滤指定url以及文件上传url
        ServerHttpRequest request = exchange.getRequest().mutate().headers(httpHeaders -> {
            // 设置traceId
            httpHeaders.put(TraceIdUtil.TRACE_ID, Lists.newArrayList(TraceIdUtil.initTraceId()));
        }).build();

        // 请求路径
        String requestPath = request.getPath().pathWithinApplication().value();
        // 过滤指定请求的url
        if (excludeUrl.excludeUrls(requestPath)) {
            return noHandler(exchange, chain);
        }

        MediaType mediaType = request.getHeaders().getContentType();
        // 过滤上传文件请求,
        if ((mediaType != null && mediaType.equals(MediaType.MULTIPART_FORM_DATA))) {
            return noHandler(exchange, chain);
        }
        return null;
    }

    private Mono<Void> noHandler(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 清除traceId
            TraceIdUtil.clear();
        }));
    }



}
